package com.lpb.spring.lpbspring.context;

import com.lpb.spring.lpbspring.ioc.BeanPostProcessor;
import com.lpb.spring.lpbspring.ioc.PreBuildBeanFactory;
import org.apache.commons.collections.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @ClassName AbstractApplicationContext
 * @Description TODO
 * @date 2022/12/19 00:58
 * @Version 1.0
 * @authoe linpengbo
 */
public abstract class AbstractApplicationContext implements ApplicationContext{

    protected PreBuildBeanFactory beanFactory;

    public AbstractApplicationContext(){
        super();
        this.beanFactory=new PreBuildBeanFactory();
    }


    /**
     * 主要方法-解析bean和注册bean
     */
    protected void refresh() throws Exception {

        beanFactory.registerTypeMap();

        //注册beanpostprocessor
        doRegisterBeanPostProcessor();

        //注册单例bean
        beanFactory.preInstantiateSingletons();

    }

    private   void doRegisterBeanPostProcessor()throws Exception{
        //从beanfactory中得到所有用户配置的beanpostprocessor类型的bean实例 注册到beanfacory
        List<BeanPostProcessor> beanPostProcessors= beanFactory.getBeansOfTypeList(BeanPostProcessor.class);
        if(CollectionUtils.isNotEmpty(beanPostProcessors)){
            for (BeanPostProcessor bpp:beanPostProcessors) {
                beanFactory.registerBeanPostProcess(bpp);
            }
        }
    }

    @Override
    public Class<?> getType(String beanName) throws Exception {
        return this.beanFactory.getType(beanName);
    }

    @Override
    public Object getBean(String beanName) throws Exception {
        return this.beanFactory.getBean(beanName);
    }

    @Override
    public <T> T getBean(Class<T> clazz) throws Exception {
        return this.beanFactory.getBean(clazz);
    }

    @Override
    public <T> Map<String, T> getBeansOfType(Class<T> type) throws Exception {
        return this.beanFactory.getBeansOfType(type);
    }

    @Override
    public <T> List<T> getBeansOfTypeList(Class<T> type) throws Exception {
        return this.beanFactory.getBeansOfTypeList(type);
    }

    @Override
    public void registerBeanPostProcess(BeanPostProcessor bpp) {
        this.beanFactory.registerBeanPostProcess(bpp);
    }
}
